package com.bingoogolapple.qrcode.core;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.render.PixelMapHolder;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;
import ohos.global.resource.NotExistException;
import ohos.media.image.PixelMap;

import java.io.IOException;

public class ScanBoxView extends Component implements Component.DrawTask {

    private static final long ANIMATION_DELAY = 10L;
    private int mMoveStepDistance;
    private int mAnimDelayTime;

    private Rect mFramingRect;
    private float mScanLineTop;
    private float mScanLineLeft;
    private Paint mPaint;
    //private TextPaint mTipPaint;

    private int mMaskColor;
    private int mCornerColor;
    private int mCornerLength;
    private int mCornerSize;
    private int mRectWidth;
    private int mRectHeight;
    private int mBarcodeRectHeight;
    private int mTopOffset;
    private int mScanLineSize;
    private int mScanLineColor;
    private int mScanLineMargin;
    private boolean mIsShowDefaultScanLineDrawable;
    //private Drawable mCustomScanLineDrawable;
    private PixelMap mScanLineBitmap;
    private int mBorderSize;
    private int mBorderColor;
    private int mAnimTime;
    private float mVerticalBias;
    private int mCornerDisplayType;
    private int mToolbarHeight;
    private boolean mIsBarcode;
    private String mQRCodeTipText;
    private String mBarCodeTipText;
    private String mTipText;
    private int mTipTextSize;
    private int mTipTextColor;
    private boolean mIsTipTextBelowRect;
    private int mTipTextMargin;
    private boolean mIsShowTipTextAsSingleLine;
    private int mTipBackgroundColor;
    private boolean mIsShowTipBackground;
    private boolean mIsScanLineReverse;
    private boolean mIsShowDefaultGridScanLineDrawable;
    //private Drawable mCustomGridScanLineDrawable;
    private PixelMap mGridScanLineBitmap;
    private float mGridScanLineBottom;
    private float mGridScanLineRight;

    private PixelMap mOriginQRCodeScanLineBitmap;
    private PixelMap mOriginBarCodeScanLineBitmap;
    private PixelMap mOriginQRCodeGridScanLineBitmap;
    private PixelMap mOriginBarCodeGridScanLineBitmap;


    private float mHalfCornerSize;
    //private StaticLayout mTipTextSl;
    private int mTipBackgroundRadius;

    private boolean mIsOnlyDecodeScanBoxArea;
    private boolean mIsShowLocationPoint;
    private boolean mIsAutoZoom;
    private boolean mSizeChange;

    private QRCodeView mQRCodeView;
    private PixelMapElement mScanLineElement;
    private EventHandler eventHandler;

    public ScanBoxView(Context context) {
        super(context);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mMaskColor = Color.getIntColor("#33FFFFFF");
        LogUtil.info("ScanBoxView..");
        this.addDrawTask(this);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mMaskColor = Color.getIntColor("#33FFFFFF");
        mCornerColor = Color.WHITE.getValue();
        mCornerLength = BGAQRCodeUtil.dp2px(context, 20);
        mCornerSize = BGAQRCodeUtil.dp2px(context, 3);
        mScanLineSize = BGAQRCodeUtil.dp2px(context, 1);
        mScanLineColor = Color.WHITE.getValue();
        mTopOffset = BGAQRCodeUtil.dp2px(context, 90);
        mRectWidth = BGAQRCodeUtil.dp2px(context, 200);
        mRectHeight = BGAQRCodeUtil.dp2px(context, 200);
        mBarcodeRectHeight = BGAQRCodeUtil.dp2px(context, 140);
        mScanLineMargin = 0;
        mIsShowDefaultScanLineDrawable = false;
        //mCustomScanLineDrawable = null;
        mScanLineBitmap = null;
        mBorderSize = BGAQRCodeUtil.dp2px(context, 1);
        mBorderColor = Color.WHITE.getValue();
        mAnimTime = 1000;
        mVerticalBias = -1;
        mCornerDisplayType = 1;
        mToolbarHeight = 0;
        mIsBarcode = false;
        mMoveStepDistance = BGAQRCodeUtil.dp2px(context, 2);
        mTipText = null;
        mTipTextSize = BGAQRCodeUtil.sp2px(context, 14);
        mTipTextColor = Color.WHITE.getValue();
        mIsTipTextBelowRect = false;
        mTipTextMargin = BGAQRCodeUtil.dp2px(context, 20);
        mIsShowTipTextAsSingleLine = false;
        mTipBackgroundColor = Color.getIntColor("#22000000");
        mIsShowTipBackground = false;
        mIsScanLineReverse = false;
        mIsShowDefaultGridScanLineDrawable = false;
//
//        mTipPaint = new TextPaint();
//        mTipPaint.setAntiAlias(true);

        mTipBackgroundRadius = BGAQRCodeUtil.dp2px(context, 4);

        mIsOnlyDecodeScanBoxArea = false;
        mIsShowLocationPoint = false;
        mIsAutoZoom = false;
        mSizeChange = true;

    }

    public ScanBoxView(Context context, AttrSet attrSet) {
        super(context, attrSet);
    }

    public ScanBoxView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
    }

    public ScanBoxView(Context context, AttrSet attrSet, int resId) {
        super(context, attrSet, resId);
    }

    void init(QRCodeView qrCodeView, AttrSet attrSet, Context context) {
        mQRCodeView = qrCodeView;
        mTopOffset = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_topOffset", mTopOffset);
        mCornerSize = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_cornerSize", mCornerSize);
        mCornerLength = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_cornerLength", mCornerLength);
        mScanLineSize = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_scanLineSize", mScanLineSize);
        mRectWidth = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_rectWidth", mRectWidth);
        mMaskColor = TypedAttrUtils.getIntColor(attrSet, "qrcv_maskColor", mMaskColor);
        mScanLineElement=(PixelMapElement)TypedAttrUtils.getElementFromAttr(attrSet,"qrcv_customScanLineDrawable",new PixelMapElement(ResourceUtil.decodeResource(context,ResourceTable.Media_qrcode_default_scan_line)));
        mCornerColor = TypedAttrUtils.getIntColor(attrSet, "qrcv_cornerColor", mCornerColor);
        mScanLineColor = TypedAttrUtils.getIntColor(attrSet, "qrcv_scanLineColor", mScanLineColor);
        mScanLineMargin = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_scanLineMargin", mScanLineMargin);
        mIsShowDefaultScanLineDrawable = TypedAttrUtils.getBoolean(attrSet, "qrcv_isShowDefaultScanLineDrawable", mIsShowDefaultScanLineDrawable);
        mBorderSize = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_borderSize", mBorderSize);
        mBorderColor = TypedAttrUtils.getIntColor(attrSet, "qrcv_borderColor", mBorderColor);
        mAnimTime = TypedAttrUtils.getInteger(attrSet, "qrcv_animTime", mAnimTime);
        mVerticalBias = TypedAttrUtils.getFloat(attrSet, "qrcv_verticalBias", mVerticalBias);
        String mDisplayType=TypedAttrUtils.getString(attrSet, "qrcv_cornerDisplayType", "center");
        if("center".equals(mDisplayType)){
            mCornerDisplayType=1;
        }else{
            mCornerDisplayType=2;
        }
        mBarcodeRectHeight = TypedAttrUtils.getDimensionPixelSize(attrSet, "qrcv_barcodeRectHeight", mBarcodeRectHeight);
        mIsBarcode = TypedAttrUtils.getBoolean(attrSet, "qrcv_isBarcode", mIsBarcode);
        mIsScanLineReverse = TypedAttrUtils.getBoolean(attrSet, "qrcv_isScanLineReverse", mIsScanLineReverse);
        mIsShowDefaultGridScanLineDrawable = TypedAttrUtils.getBoolean(attrSet, "qrcv_isShowDefaultGridScanLineDrawable", mIsShowDefaultGridScanLineDrawable);
        mIsOnlyDecodeScanBoxArea = TypedAttrUtils.getBoolean(attrSet, "qrcv_isOnlyDecodeScanBoxArea", mIsOnlyDecodeScanBoxArea);
        mIsShowLocationPoint = TypedAttrUtils.getBoolean(attrSet, "qrcv_isShowLocationPoint", mIsShowLocationPoint);
        mIsAutoZoom = TypedAttrUtils.getBoolean(attrSet, "qrcv_isAutoZoom", mIsAutoZoom);

        afterInitCustomAttrs(context);
    }

    private void afterInitCustomAttrs(Context context) {
        eventHandler=new EventHandler(EventRunner.current()){
            @Override
            protected void processEvent(InnerEvent event) {
               invalidate();
            }
        };

        try {
            if(mIsShowDefaultScanLineDrawable){
                mOriginQRCodeScanLineBitmap = ResourceUtil.getPixelmap(context, ResourceTable.Media_qrcode_default_scan_line);
                mOriginBarCodeScanLineBitmap = BGAQRCodeUtil.adjustPhotoRotation(mOriginQRCodeScanLineBitmap, 90);

            }else{
                mOriginQRCodeScanLineBitmap = mScanLineElement.getPixelMap();
                mOriginBarCodeScanLineBitmap = BGAQRCodeUtil.adjustPhotoRotation(mOriginQRCodeScanLineBitmap, 90);
            }
            if(mIsShowDefaultGridScanLineDrawable){
                mOriginQRCodeGridScanLineBitmap=ResourceUtil.getPixelmap(context, ResourceTable.Media_qrcode_default_grid_scan_line);
                mOriginBarCodeGridScanLineBitmap = BGAQRCodeUtil.adjustPhotoRotation(mOriginQRCodeGridScanLineBitmap, 90);
                mOriginBarCodeGridScanLineBitmap = BGAQRCodeUtil.adjustPhotoRotation(mOriginBarCodeGridScanLineBitmap, 90);
                mOriginBarCodeGridScanLineBitmap = BGAQRCodeUtil.adjustPhotoRotation(mOriginBarCodeGridScanLineBitmap, 90);
            }
        }catch (IOException e){
            LogUtil.error(e.getMessage());
        }catch (NotExistException e){
            LogUtil.error(e.getMessage());
        }
        mTopOffset += mToolbarHeight;
        mHalfCornerSize = 1.0f * mCornerSize / 2;

        setIsBarcode(mIsBarcode);
    }


    void onSizeChanged() {
        if (!mSizeChange) {
            return;
        }
        mSizeChange = false;
        calFramingRect();
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {

        onSizeChanged();

        // 画遮罩层
        drawMask(component, canvas);

        // 画边框线
        drawBorderLine(canvas);

        // 画四个直角的线
        drawCornerLine(canvas);

        // 画扫描线
        drawScanLine(canvas);

        // 移动扫描线的位置
        moveScanLine();
        eventHandler.sendEvent(0,ANIMATION_DELAY);
    }


    private void calFramingRect() {
        int leftOffset = (getWidth() - mRectWidth) / 2;
        mFramingRect = new Rect(leftOffset, mTopOffset, leftOffset + mRectWidth, mTopOffset + mRectHeight);

        if (mIsBarcode) {
            mGridScanLineRight = mScanLineLeft = mFramingRect.left + mHalfCornerSize + 0.5f;
        } else {
            mGridScanLineBottom = mScanLineTop = mFramingRect.top + mHalfCornerSize + 0.5f;
        }

        if (mQRCodeView != null && isOnlyDecodeScanBoxArea()) {
            mQRCodeView.onScanBoxRectChanged(new Rect(mFramingRect));
        }
    }

    /*
     * 画遮罩层
     */
    private void drawMask(Component component, Canvas canvas) {
        int width = component.getWidth();
        int height = component.getHeight();

        if (mMaskColor != Color.TRANSPARENT.getValue()) {
            mPaint.setStyle(Paint.Style.FILL_STYLE);
            mPaint.setColor(new Color(mMaskColor));
            canvas.drawRect(new RectFloat(0, 0, width, mFramingRect.top), mPaint);
            canvas.drawRect(new RectFloat(0, mFramingRect.top, mFramingRect.left, mFramingRect.bottom + 1), mPaint);
            canvas.drawRect(new RectFloat(mFramingRect.right + 1, mFramingRect.top, width, mFramingRect.bottom + 1), mPaint);
            canvas.drawRect(new RectFloat(0, mFramingRect.bottom + 1, width, height), mPaint);
        }
    }

    /*
     * 画边框线
     */
    private void drawBorderLine(Canvas canvas) {
        if (mBorderSize > 0) {
            mPaint.setStyle(Paint.Style.STROKE_STYLE);
            mPaint.setColor(new Color(mBorderColor));
            mPaint.setStrokeWidth(mBorderSize);
            canvas.drawRect(CanvasUtil.trasnsRectFfromRect(mFramingRect), mPaint);
        }
    }

    /*
     * 画四个直角的线
     */
    private void drawCornerLine(Canvas canvas) {
        if (mHalfCornerSize > 0) {
            mPaint.setStyle(Paint.Style.STROKE_STYLE);
            mPaint.setColor(new Color(mCornerColor));
            mPaint.setStrokeWidth(mCornerSize);
            if (mCornerDisplayType == 1) {
                canvas.drawLine(new Point(mFramingRect.left - mHalfCornerSize, mFramingRect.top),
                        new Point(mFramingRect.left - mHalfCornerSize + mCornerLength, mFramingRect.top),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.left, mFramingRect.top - mHalfCornerSize),
                        new Point(mFramingRect.left, mFramingRect.top - mHalfCornerSize + mCornerLength),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right + mHalfCornerSize, mFramingRect.top),
                        new Point(mFramingRect.right + mHalfCornerSize - mCornerLength, mFramingRect.top),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right, mFramingRect.top - mHalfCornerSize),
                        new Point(mFramingRect.right, mFramingRect.top - mHalfCornerSize + mCornerLength),
                        mPaint);

                canvas.drawLine(new Point(mFramingRect.left - mHalfCornerSize, mFramingRect.bottom),
                        new Point(mFramingRect.left - mHalfCornerSize + mCornerLength, mFramingRect.bottom),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.left, mFramingRect.bottom + mHalfCornerSize),
                        new Point(mFramingRect.left, mFramingRect.bottom + mHalfCornerSize - mCornerLength),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right + mHalfCornerSize, mFramingRect.bottom),
                        new Point(mFramingRect.right + mHalfCornerSize - mCornerLength, mFramingRect.bottom),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right, mFramingRect.bottom + mHalfCornerSize),
                        new Point(mFramingRect.right, mFramingRect.bottom + mHalfCornerSize - mCornerLength), mPaint);
            } else if (mCornerDisplayType == 2) {
                canvas.drawLine(new Point(mFramingRect.left, mFramingRect.top + mHalfCornerSize),
                        new Point(mFramingRect.left + mCornerLength, mFramingRect.top + mHalfCornerSize),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.left + mHalfCornerSize, mFramingRect.top),
                        new Point(mFramingRect.left + mHalfCornerSize, mFramingRect.top + mCornerLength),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right, mFramingRect.top + mHalfCornerSize),
                        new Point(mFramingRect.right - mCornerLength, mFramingRect.top + mHalfCornerSize),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right - mHalfCornerSize, mFramingRect.top),
                        new Point(mFramingRect.right - mHalfCornerSize, mFramingRect.top + mCornerLength),
                        mPaint);

                canvas.drawLine(new Point(mFramingRect.left, mFramingRect.bottom - mHalfCornerSize),
                        new Point(mFramingRect.left + mCornerLength, mFramingRect.bottom - mHalfCornerSize), mPaint);
                canvas.drawLine(new Point(mFramingRect.left + mHalfCornerSize, mFramingRect.bottom),
                        new Point(mFramingRect.left + mHalfCornerSize, mFramingRect.bottom - mCornerLength), mPaint);
                canvas.drawLine(new Point(mFramingRect.right, mFramingRect.bottom - mHalfCornerSize),
                        new Point(mFramingRect.right - mCornerLength, mFramingRect.bottom - mHalfCornerSize),
                        mPaint);
                canvas.drawLine(new Point(mFramingRect.right - mHalfCornerSize, mFramingRect.bottom),
                        new Point(mFramingRect.right - mHalfCornerSize, mFramingRect.bottom - mCornerLength),
                        mPaint);
            }
        }
    }

    /*
     * 画扫描线
     */
    private void drawScanLine(Canvas canvas) {
        if (mIsBarcode) {
            if (mGridScanLineBitmap != null) {
                RectFloat dstGridRectF = new RectFloat(mFramingRect.left + mHalfCornerSize + 0.5f, mFramingRect.top + mHalfCornerSize + mScanLineMargin,
                        mGridScanLineRight, mFramingRect.bottom - mHalfCornerSize - mScanLineMargin);

                Rect srcGridRect = new Rect((int) (mGridScanLineBitmap.getImageInfo().size.height - dstGridRectF.getWidth()),
                        0, mGridScanLineBitmap.getImageInfo().size.width,
                        mGridScanLineBitmap.getImageInfo().size.height);

                if (srcGridRect.left < 0) {
                    srcGridRect.left = 0;
                    dstGridRectF.left = dstGridRectF.right - srcGridRect.getWidth();
                }
                canvas.drawPixelMapHolderRect(new PixelMapHolder(mGridScanLineBitmap),
                        CanvasUtil.trasnsRectFfromRect(srcGridRect), dstGridRectF, mPaint);
            } else if (mScanLineBitmap != null) {
                RectFloat lineRect = new RectFloat(mScanLineLeft, mFramingRect.top + mHalfCornerSize + mScanLineMargin, mScanLineLeft + mScanLineBitmap.getImageInfo().size.width,
                        mFramingRect.bottom - mHalfCornerSize - mScanLineMargin);
                canvas.drawPixelMapHolderRect(new PixelMapHolder(mScanLineBitmap), new RectFloat(0,0,mScanLineBitmap.getImageInfo().size.width,mScanLineBitmap.getImageInfo().size.height), lineRect, mPaint);
            } else {

                mPaint.setStyle(Paint.Style.FILL_STYLE);
                mPaint.setColor(new Color(mScanLineColor));
                canvas.drawRect(new RectFloat(mScanLineLeft, mFramingRect.top + mHalfCornerSize + mScanLineMargin, mScanLineLeft + mScanLineSize,
                        mFramingRect.bottom - mHalfCornerSize - mScanLineMargin), mPaint);
            }
        } else {
            if (mGridScanLineBitmap != null) {
                RectFloat dstGridRectF = new RectFloat(mFramingRect.left + mHalfCornerSize + mScanLineMargin, mFramingRect.top + mHalfCornerSize + 0.5f,
                        mFramingRect.right - mHalfCornerSize - mScanLineMargin, mGridScanLineBottom);

                Rect srcRect = new Rect(0, (int) (mGridScanLineBitmap.getImageInfo().size.height - dstGridRectF.getHeight()),
                        mGridScanLineBitmap.getImageInfo().size.width, mGridScanLineBitmap.getImageInfo().size.height);

                if (srcRect.top < 0) {
                    srcRect.top = 0;
                    dstGridRectF.top = dstGridRectF.bottom - srcRect.getHeight();
                }
                canvas.drawPixelMapHolderRect(new PixelMapHolder(mGridScanLineBitmap), CanvasUtil.trasnsRectFfromRect(srcRect), dstGridRectF, mPaint);
            } else if (mScanLineBitmap != null) {
                RectFloat lineRect = new RectFloat(mFramingRect.left + mHalfCornerSize + mScanLineMargin, mScanLineTop,
                        mFramingRect.right - mHalfCornerSize - mScanLineMargin,
                        mScanLineTop + mScanLineBitmap.getImageInfo().size.height);
                canvas.drawPixelMapHolderRect(new PixelMapHolder(mScanLineBitmap), new RectFloat(0,0,mScanLineBitmap.getImageInfo().size.width,mScanLineBitmap.getImageInfo().size.height), lineRect, mPaint);
            } else {
                mPaint.setStyle(Paint.Style.FILL_STYLE);
                mPaint.setColor(new Color(mScanLineColor));
                canvas.drawRect(new RectFloat(mFramingRect.left + mHalfCornerSize + mScanLineMargin, mScanLineTop, mFramingRect.right - mHalfCornerSize - mScanLineMargin,
                        mScanLineTop + mScanLineSize), mPaint);
            }
        }
    }


    /**
     * 移动扫描线的位置
     */
    private void moveScanLine() {

        if (mIsBarcode) {
            if (mGridScanLineBitmap == null) {
                // 处理非网格扫描图片的情况
                mScanLineLeft += mMoveStepDistance;
                int scanLineSize = mScanLineSize;
                if (mScanLineBitmap != null) {
                    scanLineSize = mScanLineBitmap.getImageInfo().size.width;
                }

                if (mIsScanLineReverse) {
                    if (mScanLineLeft + scanLineSize > mFramingRect.right - mHalfCornerSize || mScanLineLeft < mFramingRect.left + mHalfCornerSize) {
                        mMoveStepDistance = -mMoveStepDistance;
                    }
                } else {
                    if (mScanLineLeft + scanLineSize > mFramingRect.right - mHalfCornerSize) {
                        mScanLineLeft = mFramingRect.left + mHalfCornerSize + 0.5f;
                    }
                }
            } else {
                // 处理网格扫描图片的情况
                mGridScanLineRight += mMoveStepDistance;
                if (mGridScanLineRight > mFramingRect.right - mHalfCornerSize) {
                    mGridScanLineRight = mFramingRect.left + mHalfCornerSize + 0.5f;
                }
            }
        } else {
            if (mGridScanLineBitmap == null) {
                // 处理非网格扫描图片的情况
                mScanLineTop += mMoveStepDistance;
                int scanLineSize = mScanLineSize;
                if (mScanLineBitmap != null) {
                    scanLineSize = mScanLineBitmap.getImageInfo().size.height;
                }

                if (mIsScanLineReverse) {
                    if (mScanLineTop + scanLineSize > mFramingRect.bottom - mHalfCornerSize || mScanLineTop < mFramingRect.top + mHalfCornerSize) {
                        mMoveStepDistance = -mMoveStepDistance;
                    }
                } else {
                    if (mScanLineTop + scanLineSize > mFramingRect.bottom - mHalfCornerSize) {
                        mScanLineTop = mFramingRect.top + mHalfCornerSize + 0.5f;
                    }
                }
            } else {
                // 处理网格扫描图片的情况
                mGridScanLineBottom += mMoveStepDistance;
                if (mGridScanLineBottom > mFramingRect.bottom - mHalfCornerSize) {
                    mGridScanLineBottom = mFramingRect.top + mHalfCornerSize + 0.5f;
                }
            }

        }
    }

    public Rect getScanBoxAreaRect(int previewHeight) {
        if (mIsOnlyDecodeScanBoxArea && getVisibility() == VISIBLE) {
            Rect rect = new Rect(mFramingRect);
            float ratio = 1.0f * previewHeight / 1;

            float centerX = rect.getCenterX() * ratio;
            float centerY = rect.getCenterY() * ratio;

            float halfWidth = rect.getWidth() / 2f;
            float halfHeight = rect.getHeight() / 2f;
            float newHalfWidth = halfWidth * ratio;
            float newHalfHeight = halfHeight * ratio;

            rect.left = (int) (centerX - newHalfWidth);
            rect.right = (int) (centerX + newHalfWidth);
            rect.top = (int) (centerY - newHalfHeight);
            rect.bottom = (int) (centerY + newHalfHeight);
            return rect;
        } else {
            return null;
        }
    }

    public void setIsBarcode(boolean isBarcode) {
        mIsBarcode = isBarcode;
        refreshScanBox();
    }

    private void refreshScanBox() {
        if (mIsShowDefaultGridScanLineDrawable) {
            if (mIsBarcode) {
                mGridScanLineBitmap = mOriginBarCodeGridScanLineBitmap;
            } else {
                mGridScanLineBitmap = mOriginQRCodeGridScanLineBitmap;
            }
        } else if (mIsShowDefaultScanLineDrawable) {
            if (mIsBarcode) {
                mScanLineBitmap = mOriginBarCodeScanLineBitmap;
            } else {
                mScanLineBitmap = mOriginQRCodeScanLineBitmap;
            }
        }

        if (mIsBarcode) {
            mTipText = mBarCodeTipText;
            mRectHeight = mBarcodeRectHeight;
            mAnimDelayTime = (int) ((1.0f * mAnimTime * mMoveStepDistance) / mRectWidth);
        } else {
            mTipText = mQRCodeTipText;
            mRectHeight = mRectWidth;
            mAnimDelayTime = (int) ((1.0f * mAnimTime * mMoveStepDistance) / mRectHeight);
        }

        if (mVerticalBias != -1) {
            int screenHeight = BGAQRCodeUtil.getScreenResolution(getContext()).getPointYToInt() - BGAQRCodeUtil.getStatusBarHeight(getContext());
            if (mToolbarHeight == 0) {
                mTopOffset = (int) (screenHeight * mVerticalBias - mRectHeight / 2);
            } else {
                mTopOffset = mToolbarHeight + (int) ((screenHeight - mToolbarHeight) * mVerticalBias - mRectHeight / 2);
            }
        }

        calFramingRect();

        invalidate();
    }


    public boolean getIsBarcode() {
        return mIsBarcode;
    }

    public int getMaskColor() {
        return mMaskColor;
    }

    public void setMaskColor(int maskColor) {
        mMaskColor = maskColor;
        refreshScanBox();
    }

    public int getCornerColor() {
        return mCornerColor;
    }

    public void setCornerColor(int cornerColor) {
        mCornerColor = cornerColor;
        refreshScanBox();
    }

    public int getCornerLength() {
        return mCornerLength;
    }

    public void setCornerLength(int cornerLength) {
        mCornerLength = cornerLength;
        refreshScanBox();
    }

    public int getCornerSize() {
        return mCornerSize;
    }

    public void setCornerSize(int cornerSize) {
        mCornerSize = cornerSize;
        refreshScanBox();
    }

    public int getRectWidth() {
        return mRectWidth;
    }

    public void setRectWidth(int rectWidth) {
        mRectWidth = rectWidth;
        refreshScanBox();
    }

    public int getRectHeight() {
        return mRectHeight;
    }

    public void setRectHeight(int rectHeight) {
        mRectHeight = rectHeight;
        refreshScanBox();
    }

    public int getBarcodeRectHeight() {
        return mBarcodeRectHeight;
    }

    public void setBarcodeRectHeight(int barcodeRectHeight) {
        mBarcodeRectHeight = barcodeRectHeight;
        refreshScanBox();
    }

    public int getTopOffset() {
        return mTopOffset;
    }

    public void setTopOffset(int topOffset) {
        mTopOffset = topOffset;
        refreshScanBox();
    }

    public int getScanLineSize() {
        return mScanLineSize;
    }

    public void setScanLineSize(int scanLineSize) {
        mScanLineSize = scanLineSize;
        refreshScanBox();
    }

    public int getScanLineColor() {
        return mScanLineColor;
    }

    public void setScanLineColor(int scanLineColor) {
        mScanLineColor = scanLineColor;
        refreshScanBox();
    }

    public int getScanLineMargin() {
        return mScanLineMargin;
    }

    public void setScanLineMargin(int scanLineMargin) {
        mScanLineMargin = scanLineMargin;
        refreshScanBox();
    }

    public boolean isShowDefaultScanLineDrawable() {
        return mIsShowDefaultScanLineDrawable;
    }

    public void setShowDefaultScanLineDrawable(boolean showDefaultScanLineDrawable) {
        mIsShowDefaultScanLineDrawable = showDefaultScanLineDrawable;
        refreshScanBox();
    }
//
//    public Drawable getCustomScanLineDrawable() {
//        return mCustomScanLineDrawable;
//    }

//    public void setCustomScanLineDrawable(Drawable customScanLineDrawable) {
//        mCustomScanLineDrawable = customScanLineDrawable;
//        refreshScanBox();
//    }

    public PixelMap getScanLineBitmap() {
        return mScanLineBitmap;
    }

    public void setScanLineBitmap(PixelMap scanLineBitmap) {
        mScanLineBitmap = scanLineBitmap;
        refreshScanBox();
    }

    public int getBorderSize() {
        return mBorderSize;
    }

    public void setBorderSize(int borderSize) {
        mBorderSize = borderSize;
        refreshScanBox();
    }

    public int getBorderColor() {
        return mBorderColor;
    }

    public void setBorderColor(int borderColor) {
        mBorderColor = borderColor;
        refreshScanBox();
    }

    public int getAnimTime() {
        return mAnimTime;
    }

    public void setAnimTime(int animTime) {
        mAnimTime = animTime;
        refreshScanBox();
    }

    public float getVerticalBias() {
        return mVerticalBias;
    }

    public void setVerticalBias(float verticalBias) {
        mVerticalBias = verticalBias;
        refreshScanBox();
    }

    public int getToolbarHeight() {
        return mToolbarHeight;
    }

    public void setToolbarHeight(int toolbarHeight) {
        mToolbarHeight = toolbarHeight;
        refreshScanBox();
    }

    public String getQRCodeTipText() {
        return mQRCodeTipText;
    }

    public void setQRCodeTipText(String qrCodeTipText) {
        mQRCodeTipText = qrCodeTipText;
        refreshScanBox();
    }

    public String getBarCodeTipText() {
        return mBarCodeTipText;
    }

    public void setBarCodeTipText(String barCodeTipText) {
        mBarCodeTipText = barCodeTipText;
        refreshScanBox();
    }

    public String getTipText() {
        return mTipText;
    }

    public void setTipText(String tipText) {
        if (mIsBarcode) {
            mBarCodeTipText = tipText;
        } else {
            mQRCodeTipText = tipText;
        }
        refreshScanBox();
    }

    public int getTipTextColor() {
        return mTipTextColor;
    }

    public void setTipTextColor(int tipTextColor) {
        mTipTextColor = tipTextColor;
        //mTipPaint.setColor(mTipTextColor);
        refreshScanBox();
    }

    public int getTipTextSize() {
        return mTipTextSize;
    }

    public void setTipTextSize(int tipTextSize) {
        mTipTextSize = tipTextSize;
        // mTipPaint.setTextSize(mTipTextSize);
        refreshScanBox();
    }

    public boolean isTipTextBelowRect() {
        return mIsTipTextBelowRect;
    }

    public void setTipTextBelowRect(boolean tipTextBelowRect) {
        mIsTipTextBelowRect = tipTextBelowRect;
        refreshScanBox();
    }

    public int getTipTextMargin() {
        return mTipTextMargin;
    }

    public void setTipTextMargin(int tipTextMargin) {
        mTipTextMargin = tipTextMargin;
        refreshScanBox();
    }

    public boolean isShowTipTextAsSingleLine() {
        return mIsShowTipTextAsSingleLine;
    }

    public void setShowTipTextAsSingleLine(boolean showTipTextAsSingleLine) {
        mIsShowTipTextAsSingleLine = showTipTextAsSingleLine;
        refreshScanBox();
    }

    public boolean isShowTipBackground() {
        return mIsShowTipBackground;
    }

    public void setShowTipBackground(boolean showTipBackground) {
        mIsShowTipBackground = showTipBackground;
        refreshScanBox();
    }

    public int getTipBackgroundColor() {
        return mTipBackgroundColor;
    }

    public void setTipBackgroundColor(int tipBackgroundColor) {
        mTipBackgroundColor = tipBackgroundColor;
        refreshScanBox();
    }

    public boolean isScanLineReverse() {
        return mIsScanLineReverse;
    }

    public void setScanLineReverse(boolean scanLineReverse) {
        mIsScanLineReverse = scanLineReverse;
        refreshScanBox();
    }

    public boolean isShowDefaultGridScanLineDrawable() {
        return mIsShowDefaultGridScanLineDrawable;
    }

    public void setShowDefaultGridScanLineDrawable(boolean showDefaultGridScanLineDrawable) {
        mIsShowDefaultGridScanLineDrawable = showDefaultGridScanLineDrawable;
        refreshScanBox();
    }

    public float getHalfCornerSize() {
        return mHalfCornerSize;
    }

    public void setHalfCornerSize(float halfCornerSize) {
        mHalfCornerSize = halfCornerSize;
        refreshScanBox();
    }


    public int getTipBackgroundRadius() {
        return mTipBackgroundRadius;
    }

    public void setTipBackgroundRadius(int tipBackgroundRadius) {
        mTipBackgroundRadius = tipBackgroundRadius;
        refreshScanBox();
    }

    public boolean isOnlyDecodeScanBoxArea() {
        return mIsOnlyDecodeScanBoxArea;
    }

    public void setOnlyDecodeScanBoxArea(boolean onlyDecodeScanBoxArea) {
        mIsOnlyDecodeScanBoxArea = onlyDecodeScanBoxArea;
        calFramingRect();
    }

    public boolean isShowLocationPoint() {
        return mIsShowLocationPoint;
    }

    public void setShowLocationPoint(boolean showLocationPoint) {
        mIsShowLocationPoint = showLocationPoint;
    }

    public boolean isAutoZoom() {
        return mIsAutoZoom;
    }

    public void setAutoZoom(boolean autoZoom) {
        mIsAutoZoom = autoZoom;
    }


}
